package org.mybatis.generator.api.plus;

import java.util.Iterator;
import java.util.List;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

/** @author wangfupeng */

public class MybatisPluginAdditionalWhere
  extends PluginAdapter
{
  public boolean validate(List<String> warnings)
  {
    return true;
  }
  
  public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable)
  {
    FullyQualifiedJavaType stringWrapper = FullyQualifiedJavaType.getStringInstance();
    
    Field additionalWhere = new Field();
    additionalWhere.setName("additionalWhere");
    additionalWhere.setVisibility(JavaVisibility.PRIVATE);
    additionalWhere.setType(stringWrapper);
    topLevelClass.addField(additionalWhere);
    
    Method setAdditionalWhere = new Method();
    setAdditionalWhere.setFinal(true);
    setAdditionalWhere.setVisibility(JavaVisibility.PUBLIC);
    setAdditionalWhere.setName("setAdditionalWhere");
    setAdditionalWhere.addParameter(new Parameter(stringWrapper, "additionalWhere"));
    setAdditionalWhere.addBodyLine("this.additionalWhere = additionalWhere;");
    topLevelClass.addMethod(setAdditionalWhere);
    
    Method getAdditionalWhere = new Method();
    getAdditionalWhere.setFinal(true);
    getAdditionalWhere.setVisibility(JavaVisibility.PUBLIC);
    getAdditionalWhere.setReturnType(stringWrapper);
    getAdditionalWhere.setName("getAdditionalWhere");
    getAdditionalWhere.addBodyLine("return additionalWhere;");
    topLevelClass.addMethod(getAdditionalWhere);
    
    return true;
  }
  
  public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement element, IntrospectedTable introspectedTable)
  {
    boolean isUpdate = false;
    Attribute attr;
    for (Iterator localIterator = element.getAttributes().iterator(); localIterator.hasNext();)
    {
      attr = (Attribute)localIterator.next();
      if (attr.getName().equalsIgnoreCase("id"))
      {
        String value = attr.getValue();
        if (!value.startsWith("Update")) {
          break;
        }
        isUpdate = true; break;
      }
    }
    XmlElement whereElement = null;
    for (Element ele : element.getElements()) {
      if ((ele instanceof XmlElement))
      {
        XmlElement e = (XmlElement)ele;
        if ("where".equals(e.getName()))
        {
          whereElement = e;
          break;
        }
      }
    }
    if (whereElement != null)
    {
      String clause = "additionalWhere";
      if (isUpdate) {
        clause = "example.additionalWhere";
      }
      XmlElement ifAdditionalWhereNotNullElement = new XmlElement("if");
      ifAdditionalWhereNotNullElement.addAttribute(new Attribute("test", clause + " != null"));
      ifAdditionalWhereNotNullElement.addElement(new TextElement("and ${" + clause + "}"));
      whereElement.addElement(ifAdditionalWhereNotNullElement);
    }
    return true;
  }
}
